package com.banmao.snake_server.netty.server;

import com.banmao.snake_core.entity.GlobalConstant;
import com.banmao.snake_core.netty.protocol.MessageCodecSharable;
import com.banmao.snake_core.netty.protocol.ProcotolFrameDecoder;
import com.banmao.snake_server.netty.handler.LoginRequestHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

// 服务端
@Slf4j
@Component
public class ServerService {

    private static volatile Channel channel = null;
    private static final Object LOCK = new Object();

    public static Channel getChannel() {
        if(channel == null) {
            synchronized (LOCK) {
                if(channel == null) {
                    openServer();
                }
            }
        }
        return channel;
    }

    private static void openServer() {
        try {
            NioEventLoopGroup boss = new NioEventLoopGroup();
            NioEventLoopGroup worker = new NioEventLoopGroup();
            channel = new ServerBootstrap()
                    .group(boss, worker)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<NioSocketChannel>() {
                        @Override
                        protected void initChannel(NioSocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new ProcotolFrameDecoder());
                            //pipeline.addLast(new LoggingHandler());
                            pipeline.addLast(new MessageCodecSharable());
                            /*pipeline.addLast(new ChannelInboundHandlerAdapter() {
                                @Override
                                public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                    log.info("Server 接收到信息: {}", msg);
                                }
                            });*/
                            pipeline.addLast(new LoginRequestHandler());
                        }
                    })
                    .bind(GlobalConstant.PORT)
                    .sync().channel();

            channel.closeFuture().addListener(future -> {
                boss.shutdownGracefully();
                worker.shutdownGracefully();
            });

        } catch (Exception e) {
            log.error("ClientService msg:{} :", e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        openServer();

    }

}
